﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foxit.PDF;
using Foxit.PDF.Imaging;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;
using Sustainalytics.Entities.RiskRatings;
using Sustainalytics.Reporting.Framework;

namespace Sustainalytics.RiskRatings.Reporting
{
    class RiskRating_CustomColumnChartGroup : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }
        public float Width { get; set; }
        public float Height { get; set; }
        public List<RiskRatingCluster> RiskRatingClusterList { get; set; }
        public IEnumerable<RiskRatingDataPoint> UniverseChartValues { get; set; }
        public IEnumerable<RiskRatingDataPoint> IndustryChartValues { get; set; }
        public IEnumerable<RiskRatingDataPoint> SubIndustryChartValues { get; set; }
        public string Assessment { get; set; }

        private Group Elements()
        {
            var elements = new Group();
            Dictionary<string, RiskRatingCluster> ClusterDict = RiskRatingClusterList.ToDictionary(x => x.Code);

            float verticalDotSize, horisontalDotSize, columnWidth, maxValueXAxis, maxValueYAxis;

            if(UniverseChartValues == null)
                UniverseChartValues = Enumerable.Empty<RiskRatingDataPoint>();
            if (IndustryChartValues == null)
                IndustryChartValues = Enumerable.Empty<RiskRatingDataPoint>();
            if (SubIndustryChartValues == null)
                SubIndustryChartValues = Enumerable.Empty<RiskRatingDataPoint>();

            maxValueXAxis = 0;
            if (UniverseChartValues.Any())
                maxValueXAxis = UniverseChartValues.Max(x => x.XValue);
            if (IndustryChartValues.Any())
                maxValueXAxis = Math.Max(maxValueXAxis, IndustryChartValues.Max(x => x.XValue));
            if (SubIndustryChartValues.Any())
                maxValueXAxis = Math.Max(maxValueXAxis, SubIndustryChartValues.Max(x => x.XValue));

            float maxValueY = 0;
            if (UniverseChartValues.Any())
                maxValueY = UniverseChartValues.Max(x => x.YValue);
            if (IndustryChartValues.Any())
                maxValueY = Math.Max(maxValueY, IndustryChartValues.Max(x => x.YValue));
            if (SubIndustryChartValues.Any())
                maxValueY = Math.Max(maxValueY, SubIndustryChartValues.Max(x => x.YValue));

            maxValueXAxis++;

            var YAxisSteppingValue = (int)(maxValueY * 5 / 16);
            maxValueYAxis = ((int)maxValueY / YAxisSteppingValue + 1) * YAxisSteppingValue;
            verticalDotSize = (Height - 80) / maxValueYAxis;
            horisontalDotSize = (Width - 20) / maxValueXAxis;
            columnWidth = ((Width / maxValueXAxis) - 14f) / 3;
            Point chartRootPoint = new Point((int)Left + 20, (int)(Top + Height) - 70);
            float increment;

            //the chart drawings
            if (UniverseChartValues != null && UniverseChartValues.Any())
            {
                increment = 9f;
                //increment = 0f;

                foreach (RiskRatingDataPoint dataPoint in UniverseChartValues)
                {
                    //RgbColor color = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.Universe];
                    RgbColor color = new RgbColor(204, 204, 204);

                    elements.Add(new Line(chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y,
                                chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y - dataPoint.YValue * verticalDotSize,
                                columnWidth, color));

                    elements.Add(new Label(dataPoint.YValue.ToString()+"%",
                            chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment - 7f,
                            chartRootPoint.Y - dataPoint.YValue * verticalDotSize - 10f,
                            columnWidth,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Right, RgbColor.Black));
                }
            }

            if (IndustryChartValues != null && IndustryChartValues.Any())
            {
                increment = 9f + columnWidth + 2f;

                foreach (RiskRatingDataPoint dataPoint in IndustryChartValues)
                {
                    //RgbColor color = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.SubIndustry];
                    RgbColor color = new RgbColor(142, 174, 200);

                    elements.Add(new Line(chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y,
                                chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y - dataPoint.YValue * verticalDotSize,
                                columnWidth, color));

                    elements.Add(new Label(dataPoint.YValue.ToString() + "%",
                            chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment - 7f,
                            chartRootPoint.Y - dataPoint.YValue * verticalDotSize - 10,
                            columnWidth,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Right, RgbColor.Black));
                }
            }

            if (SubIndustryChartValues != null && SubIndustryChartValues.Any())
            {
                increment = 9f + (columnWidth + 2f) * 2;

                foreach (RiskRatingDataPoint dataPoint in SubIndustryChartValues)
                {
                    //RgbColor color = ReportHelper.RiskRatingTypesColors[RiskRatingTypes.SubIndustry];

                    RgbColor color = new RgbColor(29, 96, 143);

                    elements.Add(new Line(chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y,
                                chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment,
                                chartRootPoint.Y - dataPoint.YValue * verticalDotSize,
                                columnWidth, color));

                    elements.Add(new Label(dataPoint.YValue.ToString() + "%",
                            chartRootPoint.X + dataPoint.XValue * horisontalDotSize + increment - 7f,
                            chartRootPoint.Y - dataPoint.YValue * verticalDotSize - 10f,
                            columnWidth,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Right, RgbColor.Black));
                }
            }

            // the chart axis
            elements.Add(new Line(chartRootPoint.X,
                        chartRootPoint.Y,
                        Left + Width,
                        chartRootPoint.Y,
                        1f, RgbColor.Black));


            var index = 0;

            foreach (var cluster in RiskRatingClusterList)
            {
                if (cluster.Assessment.ToString() == Assessment)
                {
                    elements.Add(new Foxit.PDF.PageElements.Rectangle(chartRootPoint.X + index * horisontalDotSize, chartRootPoint.Y, horisontalDotSize, 14f,
                        RgbColor.Black, RgbColor.White, 1f, LineStyle.Solid));
                }

                elements.Add(new Label(cluster.Assessment.ToString(),
                    chartRootPoint.X + index * horisontalDotSize,
                    chartRootPoint.Y + 5f,
                    horisontalDotSize,
                    6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));

                index++;
            }


            elements.Add(new Label(ClusterDict["X"].Assessment.ToString(),
                            chartRootPoint.X,
                            chartRootPoint.Y + 5f,
                            horisontalDotSize,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));
            elements.Add(new Label(ClusterDict["A"].Assessment.ToString(),
                            chartRootPoint.X + 1 * horisontalDotSize,
                            chartRootPoint.Y + 5f,
                            horisontalDotSize,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));
            elements.Add(new Label(ClusterDict["B"].Assessment.ToString(),
                            chartRootPoint.X + 2 * horisontalDotSize,
                            chartRootPoint.Y + 5f,
                            horisontalDotSize,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));
            elements.Add(new Label(ClusterDict["C"].Assessment.ToString(),
                            chartRootPoint.X + 3 * horisontalDotSize,
                            chartRootPoint.Y + 5f,
                            horisontalDotSize,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));
            elements.Add(new Label(ClusterDict["D"].Assessment.ToString(),
                            chartRootPoint.X + 4 * horisontalDotSize,
                            chartRootPoint.Y + 5f,
                            horisontalDotSize,
                            6f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));


            return elements;
        }

        public override void Draw(PageWriter writer)
        {
            var elements = Elements();

            writer.Write_q_(true);
            elements.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
